package com.qbccn.usercenter.config;

import com.qbccn.usercenter.service.impl.CustomUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author linke
 * @date 2020/5/23 18:12
 * @description
 */
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled =true) //使用注解授权
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired  // 登录成功，自定义返回结果
    private AjaxAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired  //  登录失败返，自定义返回结果
    private AjaxAuthenticationFailureHandler authenticationFailureHandler;

    //注入我们加密的方式，spring5+以上必须要加密密码，这是官网推荐的加密方式，也可选择MD5
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private CustomUserDetailsServiceImpl customUserDetailsService;

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false); //允许抛出UserNotFoundException异常
        provider.setUserDetailsService(customUserDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }


    //认证----自定义认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //自定义认证
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //授权规则，除了要授权的，其他所有人能访问
        http.authorizeRequests()
                .antMatchers("/admin/**").hasAnyRole("admin")
                .antMatchers("/user/**").hasAnyRole("user")
                .antMatchers("/").authenticated() //需要登录后才能访问
                .anyRequest().permitAll();

        //自定义登陆返回的结果，用于ajax异步
        http.formLogin().successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler).permitAll();


        //注销功能 ,跳回首页
        //关闭跨域认证请求，否则你需要post来注销
        http.logout().logoutSuccessUrl("/")
                .and().csrf().disable();

        //启动登陆页面
        //定制登陆页面，表单提交的路径loginProcessingUrl
        http.formLogin().loginPage("/login").loginProcessingUrl("/login");
        //支持iframe
        http.headers().frameOptions().disable();
    }
}
